/**
 * Market UI
 */
package View;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JLabel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import Model.TradeGood;
import java.awt.Color;
import java.awt.Font;
import java.util.HashMap;

/**
 * This class creates an interface for the player to
 * buy goods from the planet's market, or sell goods
 * from their ship
 * @author Whitney
 * @version 1.0
 */
public class MarketWindow extends JPanel {
	/**
	 * Hashmaps for goods in the market and on the ship
	 */
	private final HashMap<String, TradeGood> inMarket;
	
	/**
	 * Hashmaps for goods in the market and on the ship
	 */
	private final HashMap<String, TradeGood> onShip;

	/**
	 * Market button arrays for both buy and sell buttons
	 */
	private final MarketButton[] buyButtons, sellButtons;
	
	/**
	 * Leave market place button
	 */
	private final JButton cancel;
	
	/**
	 * JLabel Arrays for buying and selling
	 */
	private final JLabel[] buyNameLabels, sellNameLabels, 
	sellPriceLabels, qntyInMarket, qntyOnShip;
	
	/**
	 * Array of price labels
	 */
	private final JLabel[] buyPriceLabels;

	/**
	 * JSpinner arrays for buying and selling spinners
	 */
	private final JSpinner[] buySpinners, sellSpinners;

	/**
	 * Y location of buys
	 */
	private int buyYLocs = 50;

	/**
	 * Y location of sells
	 */
	private int sellYLocs = 50;

	/**
	 * X location of buttons
	 */
	private static final int buttonXLoc = 215;

	/**
	 * X location of labels
	 */
	private static final int LABELNAMEXLOC = 25;

	/**
	 * X location of price labels
	 */
	private static final int labelPriceXLoc = 95;

	/**
	 * X location of quantity labels
	 */
	private static final int qntyLabelXLoc = 145;

	/**
	 * X location of spinners
	 */
	private static final int SPINNERXLOC = 175;

	/**
	 * X location of Market Buttons
	 */
	private static final int MARKETX = 60;
	
	 /**
	  * Y location of Market Buttons
	  */
	private static final int MARKETBUTTONSY = 30;
	
	/**
	 * Holders for ship space and playermoney
	 */
	private final int shipSpace, playerMoney;

	/**
	 * Button listener
	 */
	private final ButtonListener listen;

	/**
	 * Spinner listener
	 */
	private final ChangeListener chListen;

	/**
	 * Integer return array
	 */
	private final int[] buttonPressed = new int[4];

	/**
	 * Various JPanels
	 */
	private final JPanel marketGoods, controls, sellGoods;
	
	/**
	 * Dimensions of the top panel
	 */
	private final Dimension topPanelDimensions = new Dimension(300, 200);
	
	/**
	 * Dimensions of bottom panel
	 */
	private final Dimension bottomPanelDimensions = new Dimension(600, 100);
	
	/**
	 * String Array of the market keys
	 */
	private final String[] marketKeys = new String[10];
	
	/**
	 * A hashmap of the output
	 */
	private final HashMap<String,Object> output = new HashMap<String,Object>();
	
	/**
	 * Instantiating the Market Window requires that the 
	 * controller pass in four parameters: goods
	 * in the market, sellable goods, goods on the ship, 
	 * and the amount of space left on the ship
	 * @param inMarket a TradeGood[] housing all the trade goods available to buy
	 * @param onShip a TradeGood[] housing all the goods on the ship
	 * @param shipSpace an int with the amount of slots available 
	 * 	to store goods on the ship
	 * @param playerMoney the amount of money a player has to spend
	 */
	public MarketWindow(HashMap<String,TradeGood> inMarket, 
			HashMap<String,TradeGood> onShip, int shipSpace, int playerMoney){
//Layout Things		
		setLayout(new BorderLayout(0, 0));
		listen = new ButtonListener();
		chListen = new SpinListener();
		this.shipSpace = shipSpace;
		this.playerMoney = playerMoney;
		marketKeys[0] = "Water";
		marketKeys[1] = "Furs";
		marketKeys[2] = "Food";
		marketKeys[3] = "Ore";
		marketKeys[4] = "Medicine";
		marketKeys[5] = "Narcotics";
		marketKeys[6] = "Firearms";
		marketKeys[7] = "Robots";
		marketKeys[8] = "Machines";
		marketKeys[9] = "Games";

//Set Control Panel
		output.put("Button", -1);
		controls = new JPanel();
		controls.setBackground(Color.GRAY);
		add(controls, BorderLayout.SOUTH);
		controls.setPreferredSize(bottomPanelDimensions);
		controls.setLayout(null);
		
		cancel = new JButton("Back to Ship");
		cancel.setBounds(10, 33, 120, 40);
		cancel.addActionListener(listen);
		controls.add(cancel);
		
//Set Buying and Selling Panels
		marketGoods = new JPanel();
		add(marketGoods, BorderLayout.WEST);
		marketGoods.setPreferredSize(topPanelDimensions);
		
		sellGoods = new JPanel();
		add(sellGoods, BorderLayout.CENTER);
		sellGoods.setPreferredSize(topPanelDimensions);
		sellGoods.setLayout(null);
		
		final JLabel lblShipimg = new JLabel("");
		lblShipimg.setBounds(124, 150, 61, 16);
		sellGoods.add(lblShipimg);
		
		final JLabel lblMarkimg = new JLabel("");
		lblMarkimg.setBounds(0, 0, 0, 0);
		lblShipimg.setBounds(124, 150, 61, 16);
		marketGoods.setLayout(null);
		marketGoods.add(lblMarkimg);
		
//Initialize Buying and Selling Panels
		buyButtons = new MarketButton[10];
		sellButtons = new MarketButton[10];
		sellSpinners = new JSpinner[10];
		buySpinners = new JSpinner[10];
		buyPriceLabels = new JLabel[10];
		sellPriceLabels = new JLabel[10];
		buyNameLabels = new JLabel[10];
		sellNameLabels = new JLabel[10];
		qntyInMarket = new JLabel[10];
		qntyOnShip = new JLabel[10];
		
		this.inMarket = inMarket;
		//this.sellables = sellables;
		this.onShip = onShip;
		
		final JLabel nameLabel = new JLabel("Item");
		nameLabel.setBounds(LABELNAMEXLOC, 15, 70, 40);
		nameLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		marketGoods.add(nameLabel);
		
		final JLabel nameLabel2 = new JLabel("Item");
		nameLabel2.setBounds(0, 34, 30, 40);
		nameLabel2.setBounds(LABELNAMEXLOC, 15, 70, 40);
		nameLabel2.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		sellGoods.add(nameLabel2);

		final JLabel priceLabel = new JLabel("Price");
		priceLabel.setBounds(labelPriceXLoc, 15, 70, 40);
		priceLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		marketGoods.add(priceLabel);
		
		final JLabel priceLabel2 = new JLabel("Price");
		priceLabel2.setBounds(0, 31, 52, 70);
		priceLabel2.setBounds(labelPriceXLoc, 15, 70, 40);
		priceLabel2.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		sellGoods.add(priceLabel2);

		final JLabel qntLabel = new JLabel("Qnt.");
		qntLabel.setBounds(qntyLabelXLoc, 15, 70, 40);
		qntLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		marketGoods.add(qntLabel);
		
		final JLabel qntLabel2 = new JLabel("Qnt.");
		qntLabel2.setBounds(qntyLabelXLoc, 15, 70, 40);
		qntLabel2.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		sellGoods.add(qntLabel2);
		
		final JLabel sellLabelMain = new JLabel("Your Goods");
		sellLabelMain.setForeground(Color.ORANGE);
		sellLabelMain.setBounds(10, 2, 120, 30);
		sellLabelMain.setFont(new Font("Krungthep", Font.BOLD, 18));
		sellGoods.add(sellLabelMain);
		
		final JLabel marketLabelMain = new JLabel("Market Goods");
		marketLabelMain.setForeground(Color.ORANGE);
		marketLabelMain.setBounds(10, 2, 160, 30);
		marketLabelMain.setFont(new Font("Krungthep", Font.BOLD, 18));
		marketGoods.add(marketLabelMain);
		
		final JLabel lblPlayerMoney = new JLabel("Money:");
		lblPlayerMoney.setForeground(Color.ORANGE);
		lblPlayerMoney.setBounds(10, 2, 160, 30);
		lblPlayerMoney.setFont(new Font("Krungthep", Font.BOLD, 18));
		controls.add(lblPlayerMoney);
		
		final JLabel avPlayerMoney = new JLabel("" + playerMoney);
		avPlayerMoney.setForeground(Color.ORANGE);
		avPlayerMoney.setBounds(99, 2, 160, 30);
		avPlayerMoney.setFont(new Font("Krungthep", Font.BOLD, 18));
		controls.add(avPlayerMoney);
			
		buildBuys();
		initSales();
	}

	/**
	 * This method instantiates and then sets all the market 
	 * buy buttons to reflect the number 
	 * of products the market has to sell
	 */
	private void buildBuys(){
		for(int i = 0; i < buyButtons.length; i++){
		//initialzie buy buttons
			buyButtons[i] = new MarketButton();
			buyButtons[i].setBounds(buttonXLoc, buyYLocs, MARKETX, MARKETBUTTONSY);
			buyButtons[i].buttonSwitch(false);
			buyButtons[i].addActionListener(listen);
		//initialize buy name labels
			buyNameLabels[i] = new JLabel("---");
			buyNameLabels[i].setBounds(LABELNAMEXLOC, buyYLocs, 70, MARKETBUTTONSY);
			//buyNameLabels[i].setVisible(false);
		//initialize buy price labels
			buyPriceLabels[i] = new JLabel("--");
			buyPriceLabels[i].setBounds(labelPriceXLoc, buyYLocs, 50, MARKETBUTTONSY);
			//buyPriceLabels[i].setVisible(false);
		//initialze qnty labels
			qntyInMarket[i] = new JLabel("--");
			qntyInMarket[i].setBounds(qntyLabelXLoc, buyYLocs, 20, MARKETBUTTONSY);
		//initialize buy spinners
			buySpinners[i] = new JSpinner();
			buySpinners[i].setBounds(SPINNERXLOC, buyYLocs + 5, 40, 20);
			buySpinners[i].setVisible(false);
			buySpinners[i].addChangeListener(chListen);
		//add to Jframe
			marketGoods.add(buySpinners[i]);
			marketGoods.add(buyNameLabels[i]);
			marketGoods.add(buyPriceLabels[i]);
			marketGoods.add(qntyInMarket[i]);
			marketGoods.add(buyButtons[i]);
			
			buyYLocs = buyYLocs + 30;
		}
		int counter = 0;
		
		for(int j = 0; j < marketKeys.length; j++){
			if(inMarket.get(marketKeys[j]) != null){
				buyNameLabels[counter].setText(marketKeys[j]);//pulls TradeGood name out of HashMap, using the provided key
				buyNameLabels[counter].setVisible(true);
				buyButtons[counter].setText("Buy");
				buyButtons[counter].setGoodType(j);
				buyButtons[counter].buttonSwitch(true);
				buyButtons[counter].setEnabled(false);
				buyPriceLabels[counter].setText("" + 
						inMarket.get(marketKeys[j]).getBaseCost());
				buyPriceLabels[counter].setVisible(true);
				
//Set Buy Spinners
				int canPurchase = 0;
				if(inMarket.get(marketKeys[j]).getQuantity() > shipSpace){
					canPurchase = shipSpace;
				}
				else{
					canPurchase = inMarket.get(marketKeys[j]).getQuantity();
				}
				
//Make objects purchasable only if the player has enough money
				int price = canPurchase * inMarket.get(marketKeys[j]).getBaseCost();
				while(price > playerMoney){
					canPurchase--;
					price = canPurchase * inMarket.get(marketKeys[j]).getBaseCost();
				}
				
				SpinnerNumberModel quanModel = new SpinnerNumberModel
						(0, 0, canPurchase, 1);
				buySpinners[counter].setModel(quanModel);
				buySpinners[counter].setVisible(true);
				qntyInMarket[counter].setText("" + inMarket.get
						(marketKeys[j]).getQuantity());

			}
			counter++;
				//if no more items set space to "----"
				//deal with this later
				
				/*else{
				buyButtons[counter].buttonSwitch(false);
				buyPriceLabels[counter].setText("--");
				buyNameLabels[counter].setText("---");
				qntyInMarket[counter].setText("--");
			}*/
		}
	}
	
	/**
	 * This method instantiates and then sets all the 
	 * market sell buttons to reflect the number 
	 * of products the player has on their ship, and is 
	 * effected buy which products markets are 
	 * willing to buy
	 */
	private void initSales(){
		for(int i = 0; i < sellButtons.length; i++){
			//Initialize sell buttons
				sellButtons[i] = new MarketButton();
				sellButtons[i].setBounds(buttonXLoc, sellYLocs, 
						MARKETX, MARKETBUTTONSY);
				sellButtons[i].buttonSwitch(false);
				sellButtons[i].addActionListener(listen);
			//initialize sell labels
				sellNameLabels[i] = new JLabel("---");
				sellNameLabels[i].setBounds(LABELNAMEXLOC, sellYLocs, 
						90, MARKETBUTTONSY);
			//initialize sell Prices
				sellPriceLabels[i] = new JLabel("--");
				sellPriceLabels[i].setBounds(labelPriceXLoc, sellYLocs, 
						50, MARKETBUTTONSY);
			//initialize qnty Labels	
				qntyOnShip[i] = new JLabel("--");
				qntyOnShip[i].setBounds(qntyLabelXLoc, sellYLocs, 20, MARKETBUTTONSY);
			//initialize sell spinners
				sellSpinners[i] = new JSpinner();
				sellSpinners[i].setBounds(SPINNERXLOC, sellYLocs + 5, 40, 20);
				sellSpinners[i].setVisible(false);
				sellSpinners[i].addChangeListener(chListen);
			//add to Jframe
				sellGoods.add(sellSpinners[i]);
				sellGoods.add(sellNameLabels[i]);
				sellGoods.add(sellButtons[i]);
				sellGoods.add(sellPriceLabels[i]);
				sellGoods.add(qntyOnShip[i]);
			sellYLocs = sellYLocs + 30;
		}
		int counter = 0;
		String buttonText = "Not Buying";
		boolean inSellables = false;
		for(int j = 0; j < marketKeys.length; j++){
			if(onShip.get(marketKeys[j]) != null){
				sellNameLabels[counter].setText(onShip.get(marketKeys[j]).getName());
				sellNameLabels[counter].setVisible(true);

////Make sell buttons only available if the peeps are buying
				for(int p=0; p < marketKeys.length; p++){
					//if(p == sellButtons[counter].getGoodType() && sellables[p] != null){
						buttonText = "Sell";
						inSellables = true;
						//sellPriceLabels[counter].setText(""+sellables[p].getBaseCost());
					//}
				}
				
				sellButtons[counter].setText(buttonText);
				sellButtons[counter].buttonSwitch(inSellables);
				
				sellPriceLabels[counter].setText("" + onShip.get
						(marketKeys[j]).getBaseCost());
				
				sellButtons[counter].setGoodType(onShip.get(marketKeys[j]).getID());
				qntyOnShip[counter].setText("" + onShip.get(marketKeys[j]).getQuantity());
//set sell Spinners
				SpinnerNumberModel quanModel = new SpinnerNumberModel
						(0, 0, onShip.get(marketKeys[j]).getQuantity(), 1);
				sellSpinners[counter].setModel(quanModel);
				sellSpinners[counter].setVisible(true);
				counter++;
			//}
			/*else{
				sellButtons[counter].buttonSwitch(false);
				sellPriceLabels[counter].setText("--");
				sellNameLabels[counter].setText("---");
				qntyOnShip[counter].setText("--");
			}*/
			}
		}
	}
	
	/**
	 * A button listener class to care for all buttons in the market window
	 * It sets up the integer arrays that will be returned when any button is pressed
	 * See getButtonPressed()
	 * @author Whitney
	 *
	 */
	private class ButtonListener implements ActionListener{
		/**
		 * Takes care of all button presses
		 * @param event The button pressed event
		 */
		public void actionPerformed (ActionEvent event){
			for(int i=0; i < buyButtons.length ; i++){
				if(inMarket.get(marketKeys[i]) != null){
					System.out.println(marketKeys[i] + "and i: " + i);
					//System.out.println(event.toString() + "\n" + buyButtons[i].toString());
					if(event.getSource().equals(buyButtons[i])){
						System.out.println("buy button pressed i: " + i);
						int amount = (Integer) buySpinners[i].getValue();
						output.put("Button", 0);
						buttonPressed[1] = buyButtons[i].getGoodType();
						output.put("itemKey", buyButtons[i].getGoodKey());
			//in market is the problem
						buttonPressed[2] = amount * inMarket.get
								(marketKeys[i]).getBaseCost();
						output.put("Quantity", amount);
					}
				}
			}
			for(int i=0; i < sellButtons.length ; i++){
				if(event.getSource().equals(sellButtons[i])){
					System.out.println(sellSpinners[i].getValue());
					int amount = (Integer) sellSpinners[i].getValue();
					output.put("Button", 1);
					System.out.println("good type: " + sellButtons[i].getGoodType());
					buttonPressed[1] = sellButtons[i].getGoodType();
					System.out.println("Good key " + sellButtons[i].getGoodKey());
					output.put("itemKey", sellButtons[i].getGoodKey());
					//buttonPressed[2] = amount * sellables[i].getBaseCost();
					output.put("Quantity", amount);
					//System.out.println("sellButtons[" + i + "].getGoodKey(): " + sellButtons[i].getGoodKey());
					output.put("itemKey", sellButtons[i].getGoodKey());
				}
			}
			if(event.getSource().equals(cancel)){
				output.put("Button", -2);
			}
		}

		/**
		 * The toString for the ButtonListener
		 * @return Returns a space because the button 
		 * listener doesn't need a toString. 
		 * */
		public String toString(){
			return "";
		}
	}
	
	/**
	 * This class knows when the spinners are changed and updated the buy buttons
	 * accordingly. Basically, this just keeps people from being able to buy 0 things
	 * @author Whitney
	 *
	 */
	private class SpinListener implements ChangeListener {
		/**
		 * Checks 
		 * @param event THe event of a pressed button
		 */
	    public void stateChanged(ChangeEvent event) {
	    	for(int i=0; i < sellSpinners.length ; i++){
	    		if(event.getSource().equals(sellSpinners[i]) && 
	    				(Integer) sellSpinners[i].getValue() == 0){
	    			sellButtons[i].setEnabled(false);
	    		}
				if(event.getSource().equals(sellSpinners[i]) && 
						(Integer) sellSpinners[i].getValue() != 0){
					sellButtons[i].setEnabled(true);
				}
	    	}
	    	for(int i=0; i < buySpinners.length ; i++){
	    		if(event.getSource().equals(buySpinners[i]) && 
	    				(Integer) buySpinners[i].getValue() == 0){
	    			buyButtons[i].setEnabled(false);
	    		}
				if(event.getSource().equals(buySpinners[i]) && 
						(Integer) buySpinners[i].getValue() != 0){
					buyButtons[i].setEnabled(true);
				}
	    	}
	    }

	    /**
		 * The toString for the ButtonListener
		 * @return Returns a space because the button 
		 * listener doesn't need a toString. 
		 * */
		public String toString(){
			return "";
		}
	}
	
	/**
	 * This class returns an integer array with a length of four that details
	 * which button was pressed, and the goods that are effected
	 * int[0] = -1(no button pressed), 0(buying goods), 
	 * 1(selling goods), -2(leaving the page)
	 * int[1] = an integer that represents a good type
	 * int[2] = the amount of money spent or received in transaction
	 * int[3] = the number of items sold or purchased in the transaction
	 * @return a length four integer array that details the 
	 * button pressed and the transaction
	 */
	public HashMap<String,Object> getButtonPressed(){
		
		//This needs to be changed back!!
		return output;//buttonPressed;
	}
}
